import { useRef, useState } from 'react';
import type { DragSourceMonitor, DropTargetMonitor } from 'ym-design';
import { YmReactDnd } from 'ym-design';

const { useDrag, useDrop } = YmReactDnd;

const boxStyle = {
  border: '1px dashed gray',
  padding: '12px 18px',
  marginBottom: '18px',
  backgroundColor: 'white',
};

interface CardProps {
  id: number;
  text: string;
  index: number;
  onMoveCard: (ragIndex: number, hoverIndex: number) => void;
}

interface DragItem {
  id: number;
  index: number;
}

interface CollectValues {
  isDragging: boolean;
}

function Card(props: CardProps) {
  const { id, text, index, onMoveCard } = props;
  const dragRef = useRef<HTMLLIElement>(null);
  const [isCanDrag, setIsCanDrag] = useState<boolean>(true);

  const [{}] = useDrop<DragItem, any, any>(
    {
      accept: 'card',
      dropNode: dragRef.current,
      collect(monitor) {
        return {};
      },
      canDrop(item, monitor: DropTargetMonitor<DragItem>) {
        //排序的话 canDrop--target.spect.canDrop(item,monitor)
        return item.id !== 2;
      },
      hover(item, monitor: DropTargetMonitor<DragItem>) {
        if (!dragRef.current) {
          return;
        }
        // // console.log('--hover--item--:', item)
        const dragIndex = item.index;
        const hoverIndex = index;
        // console.log('--Card--hover--dragIndex--hoverIndex--dragRef--canDrop--:', dragIndex, hoverIndex, dragRef.current.innerHTML);
        // Don't replace items with themselves
        if (dragIndex === hoverIndex) {
          return;
        }
        // Determine rectangle on screen
        const hoverBoundingRect = dragRef.current?.getBoundingClientRect();
        // Get vertical middle

        const hoverMiddleY =
          (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;

        // Determine mouse position
        const clientOffset = monitor.getClientOffset();
        // Get pixels to the top
        const hoverDiffy = clientOffset!.y - hoverBoundingRect.top;
        // Dragging downwards
        if (dragIndex < hoverIndex && hoverDiffy < hoverMiddleY) {
          return;
        }
        // Dragging upwards
        if (dragIndex > hoverIndex && hoverDiffy > hoverMiddleY) {
          return;
        }

        // Time to actually perform the action
        onMoveCard(dragIndex, hoverIndex);

        monitor.updateItem({ id: item.id, index: hoverIndex });

        // item.index = hoverIndex
      },
      drop(item, monitor) {
        // console.log('--Card--drop--drop--item--dropRef--', item, dragRef.current?.innerHTML)
      },
    },
    [index, dragRef.current],
  );

  const [{ isDragging }] = useDrag<DragItem, any, CollectValues>(
    {
      type: 'card',
      dragNode: dragRef.current,
      canDrag: isCanDrag,
      item: {
        id,
        index,
      },
      collect: (monitor: DragSourceMonitor<DragItem, any>) => ({
        isDragging: monitor.isDragging(),
      }),
      end(item, monitor: DragSourceMonitor<DragItem, any>) {
        // console.log('--Card--dragEnd--item--:', item)
      },
    },
    [index, dragRef.current],
  );
  const opacity = isDragging ? 0 : 1;

  return (
    <li
      ref={dragRef}
      style={{ ...boxStyle, opacity, cursor: isCanDrag ? 'move' : 'dafault' }}
    >
      {text}
      {/* -{`id:${id}`}-{`index:${index}`} */}
    </li>
  );
}

export default Card;
